package jp.gr.java_conf.yuzu_project;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jp.gr.java_conf.yuzu_project.common.CommonUtil;
import jp.gr.java_conf.yuzu_project.common.SaveDataStock;
import jp.gr.java_conf.yuzu_project.parts.SQLiteHelper;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

/**
 * セーブ＆ロード画面.
 * 
 * @author ゆずプロジェクト
 * 
 */
public class SaveActivity extends Activity {
	
	private static final String TITLE = "title";
	private static final String SUB_TITLE = "subtitle";
	private String TITLE_STRING = "SAVE";
	private String NO_DATA = "No Data...";
	private SimpleAdapter adapter;
	private List<Map<String, String>> dataList;
	private ListView saveList;
	private List<SaveDataStock> saveDataList;
	private PopupWindow  popupWindow;
	private int mPosition;
//	private AlertDialog.Builder dlg;
	private AdapterView.OnItemClickListener saveListener = new OnItemClickListener() {
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			Log.i("セーブ上書き", saveDataList.get(position).isDataFlg() + " ");
			if (!saveDataList.get(position).isDataFlg()) {
				// セーブデータが無ければ保存する
				saveCommnet(position);
			} else {
				// 既にデータがある場合は上書きするメッセージを出す
				Log.i("セーブ上書き", "通った");
				final int pos = position;
				LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				View popupView = (View)inflater.inflate(R.layout.window_popup_yes_no, null);
				popupView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
				view = findViewById(R.id.save_list);
				popupWindow = new PopupWindow(view);
				popupWindow.setContentView(popupView);
				popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
				popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
				popupWindow.showAsDropDown(view, 300, -450);
				Button yesButton = (Button) popupWindow.getContentView().findViewById(R.id.popup_yes_button);
				yesButton.setOnClickListener(new OnClickListener() {
					
					public void onClick(View v) {
						popupWindow.dismiss();
						popupWindow = null;
						saveCommnet(pos);
					}
				});
				Button noButton = (Button) popupWindow.getContentView().findViewById(R.id.popup_no_button);
				noButton.setOnClickListener(new OnClickListener() {
					
					public void onClick(View v) {
						popupWindow.dismiss();
						popupWindow = null;
					}
				});
			}
		}
	};
	private AdapterView.OnItemClickListener loadListener = new OnItemClickListener() {
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			Log.i("セーブ状況", saveDataList.get(position).isDataFlg() + " ");
			if (!saveDataList.get(position).isDataFlg()) {
				LayoutInflater inflater = getLayoutInflater();
				View layout = inflater.inflate(R.layout.save_activity_error_message, null);
				TextView title = (TextView) layout.findViewById(R.id.save_error_title);
				title.setText(getString(R.string.no_data_title));
				TextView message = (TextView) layout.findViewById(R.id.save_error_message);
				message.setText(getString(R.string.no_data_message));
				Toast toast = new Toast(getApplicationContext());
				toast.setView(layout);
				toast.show();
			} else {
				Intent intent = new Intent(SaveActivity.this, PlayActivity.class);
				intent.putExtra(CommonUtil.LOAD_DATA_INTENT, saveDataList.get(position));
				startActivity(intent);
				finish();
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_save);
		
		String intentStr = getIntent().getStringExtra(CommonUtil.SAVE_LOAD_INTENT_KEY);
		// インテント文字列がnullの場合はエラーメッセージを表示してセーブ画面を終了させる
		errorJudgment(intentStr);
		
		saveList = (ListView) findViewById(R.id.save_list);
		
		// リストビューに表示するテキスト
		dataList = dummyData();
		
		adapter = new SimpleAdapter(getApplicationContext(), dataList, android.R.layout.simple_list_item_2, new String[] {"title", "subtitle"}, new int[] {android.R.id.text1, android.R.id.text2});
		saveList.setAdapter(adapter);
		
		// DBからデータを取得しリストビューに表示
		new SaveTask().execute("");
		
		// セーブ・ロード処理
		if (intentStr != null) {
			if (intentStr.equals(CommonUtil.LOAD_INTENT)) {
				saveList.setOnItemClickListener(loadListener);	
			} else if (intentStr.equals(CommonUtil.SAVE_INTENT)) {
				Log.i("保存場所0", "a");
				saveList.setOnItemClickListener(saveListener);			
			}
		} else {
			intentStr = null;
			errorJudgment(intentStr);
		}

	}

	@Override
	protected void onPause() {
		adapter = null;
		saveList = null;
		dataList = null;
		saveDataList = null;
		saveListener = null;
		loadListener = null;
//		dlg = null;
		super.onPause();
	}
	
	/**
	 * リスト初期表示用ダミーデータ作成メソッド
	 * @return データリスト
	 */
	private List<Map<String, String>> dummyData() {
		List<Map<String, String>> dataList = new ArrayList<Map<String,String>>();
		
		for (int i = 0; i < CommonUtil.SAVE_TIMES - 1; i++) {
			Map<String, String> data = new HashMap<String, String>();
			data.put(TITLE, (i + 1) + ". " + TITLE_STRING);
			data.put(SUB_TITLE, NO_DATA);
			dataList.add(data);
		}
		return dataList;
	}
	
	/**
	 * インテントで文字列が返されなければエラーメッセージを表示してセーブ画面を終了する
	 * @param intentStr インテントで渡された文字列
	 */
	private void errorJudgment(String intentStr) {
		if (intentStr == null) {
			LayoutInflater inflater = getLayoutInflater();
			View layout = inflater.inflate(R.layout.save_activity_error_message, null);
			Toast toast = new Toast(getApplicationContext());
			toast.setView(layout);
			toast.show();
			finish();
		}
	}
	
	/**
	 * データをDBに保存
	 * @param position 保存場所
	 */
	private void savePreparation(String comment) {
		Calendar cal1 = Calendar.getInstance();
		String saveTime = cal1.get(Calendar.YEAR) + "/" + (cal1.get(Calendar.MONTH) + 1) + "/" + cal1.get(Calendar.DAY_OF_MONTH) + " " + cal1.get(Calendar.HOUR_OF_DAY) + ":" + cal1.get(Calendar.MINUTE) + ":" + cal1.get(Calendar.SECOND);
		SaveDataStock saveData = (SaveDataStock)getIntent().getSerializableExtra(CommonUtil.SAVE_OBJ_INTENT_KEY);
		saveData.setDataFlg(true);
		saveData.setNumber(mPosition + 1);
		saveData.setSaveDate(saveTime);
		if (comment != null) {
			saveData.setComment(comment);
		}
		new SaveDataTask().execute(saveData);
		
		
		
	}
	
	/**
	 * 表示用データ読み込みタスク
	 * @author ゆずプロジェクト
	 *
	 */
	private class SaveTask extends AsyncTask<String, Integer, Long> {
		
		ProgressBar loadProgress;
		
		public SaveTask() {
			super();
		}
		
		@Override
		protected void onPreExecute() {
			
			loadProgress = (ProgressBar) findViewById(R.id.save_activity_progress);
			loadProgress.setVisibility(View.VISIBLE);
			
			super.onPreExecute();
		}

		@Override
		protected Long doInBackground(String... params) {
			
			// DBからデータ取得
			saveDataList = makeDataList();
			for (int i = 0; i < CommonUtil.SAVE_TIMES - 1; i++) {
				if (saveDataList.get(i).isDataFlg()) {
					dataList.get(i).put(TITLE, saveDataList.get(i).getNumber() + ". " + saveDataList.get(i).getSaveDate());
					dataList.get(i).put(SUB_TITLE, saveDataList.get(i).getComment());
				}
			}
			
			return null;
		}

		@Override
		protected void onPostExecute(Long result) {
			loadProgress.setVisibility(View.GONE);
			loadProgress = null;
			saveList.setAdapter(adapter);
			super.onPostExecute(result);
		}
		
		/**
		 * セーブデータリスト作成
		 * @return セーブデータリスト
		 */
		private synchronized List<SaveDataStock> makeDataList() {
			
			SQLiteHelper helper = new SQLiteHelper(getApplicationContext());
			SQLiteDatabase db = helper.getWritableDatabase();
			Cursor cursor = null;
			List<SaveDataStock> saveDataList = new ArrayList<SaveDataStock>();
			SaveDataStock saveData = null;
			
			try {
				cursor = db.query(CommonUtil.TABLE_NAME, null, null, null, null, null, null);
				cursor.moveToFirst();
				int index = cursor.getColumnIndex(CommonUtil.SAVE_COLUMN);
				
				do {
					byte[] data = cursor.getBlob(index);
					ByteArrayInputStream bais = new ByteArrayInputStream(data);
					try {
						ObjectInputStream ois = new ObjectInputStream(bais);
						saveData = (SaveDataStock) ois.readObject();
					} catch (OptionalDataException e) {
						e.printStackTrace();
					} catch (StreamCorruptedException e) {
						e.printStackTrace();
					}catch (ClassNotFoundException e){
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}
					
					Log.i("_id", cursor.getInt(0) + " ");
					
					// セーブデータリスト作成
					saveDataList.add(saveData);
					saveData = null;
				} while (cursor.moveToNext());

			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				if (cursor != null) {
					cursor.close();
				}
				if (db != null) {
					db.close();
				}
				
				if (helper != null) {
					helper.close();
				}
			}
			
			saveDataList.remove(CommonUtil.SAVE_TIMES - 1);
			
			return saveDataList;
		}
		
	}
	
	/**
	 * セーブタスク
	 * @author ゆずプロジェクト
	 *
	 */
	private class SaveDataTask extends AsyncTask<SaveDataStock, Integer, Long> {
		
		private ProgressBar saveProgress;
		private TextView savingMessage;
		private int position;
		private SaveDataStock mSaveData;
		
		public SaveDataTask() {
			super();
		}
		
		@Override
		protected void onPreExecute() {
			saveProgress = (ProgressBar) findViewById(R.id.save_activity_progress);
			saveProgress.setVisibility(View.VISIBLE);
			savingMessage = (TextView) findViewById(R.id.saving_message);
			savingMessage.setVisibility(View.VISIBLE);
			super.onPreExecute();
		}
		@Override
		protected Long doInBackground(SaveDataStock... saveData) {
			Long save = 1L;
			boolean saveFlg = dataSave(saveData[0]);
			if (!saveFlg) {
				save = -1L;
			} else {
				position = saveData[0].getNumber();
				mSaveData = saveData[0];
			}
			return save;
		}

		@Override
		protected void onPostExecute(Long result) {
			saveProgress.setVisibility(View.GONE);
			savingMessage.setVisibility(View.GONE);
			saveProgress = null;
			savingMessage = null;
			if (result == -1) {
				// 失敗メッセージを出す
				LayoutInflater inflater = getLayoutInflater();
				View layout = inflater.inflate(R.layout.save_activity_error_message, null);
				TextView title = (TextView) layout.findViewById(R.id.save_error_title);
				title.setText(getString(R.string.db_error_title));
				TextView message = (TextView) layout.findViewById(R.id.save_error_message);
				message.setText(getString(R.string.db_error_message));
				Toast toast = new Toast(getApplicationContext());
				toast.setView(layout);
				toast.show();
			} else {
				dataList.get(position - 1).put(TITLE, (mSaveData.getNumber()) + ". " + mSaveData.getSaveDate());
				dataList.get(position - 1).put(SUB_TITLE, mSaveData.getComment());
				saveList.setAdapter(adapter);
				saveDataList.get(position - 1).setDataFlg(true); 
			}
			super.onPostExecute(result);
		}
		
		/**
		 * プレイ画面から受け取ったデータをDBに保存する
		 * @param saveData セーブデータ
		 * @return true:成功/false:失敗
		 */
		private synchronized boolean dataSave(SaveDataStock saveData) {
			boolean saveFlg = true;
			
			SQLiteHelper helper = new SQLiteHelper(getApplicationContext());
			SQLiteDatabase db = helper.getWritableDatabase();
			try {
				ContentValues cv = new ContentValues();
				
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				try {
					ObjectOutputStream oos = new ObjectOutputStream(baos);
					oos.writeObject(saveData);
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				byte[] value = baos.toByteArray();
				
				cv.put(CommonUtil.SAVE_COLUMN, value);
				
				String[] whereArgs = new String[1];
				whereArgs[0] = String.valueOf(saveData.getNumber());
				int save = db.update(CommonUtil.TABLE_NAME, cv, "_id = ?", whereArgs);
				
				if (save == -1) {
					saveFlg = false;
				}
				
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				
				if (db != null) {
					db.close();
					db = null;
				}
			}
			
			return saveFlg;
		}
	}
	
	/**
	 * コメント保存
	 * @param position
	 */
	private void saveCommnet(int position) {
		mPosition = position;
		savePreparation(null);
//		final EditText editView = new EditText(getApplicationContext());
//		dlg = new AlertDialog.Builder(getApplicationContext());
//		dlg.setIcon(android.R.drawable.ic_dialog_info)
//	        .setTitle(getString(R.string.save_comment_title))
//	        //setViewにてビューを設定します。
//	        .setView(editView)
//	        .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
//	            public void onClick(DialogInterface dialog, int whichButton) {
//	                savePreparation(editView.getText().toString());
//	            }
//	        })
//	        .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
//	            public void onClick(DialogInterface dialog, int whichButton) {
//	            	savePreparation(null);
//	            }
//	        });
	}

}
